package com.cjx.auth.config;

import com.cjx.auth.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import java.util.ArrayList;
import java.util.List;

/**
*@Description 认证中心配置
*@Verson v1.0.0
*@Author cjunxian
*@Date
*/
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {

    private static final String clientId = "cjx-alibaba";

    private static final String  secret = "cjx-secret";

    private static final Integer tokenSecond = 3600 * 24;

    private Integer refreshTokenSecond = 3600 * 24 * 7;

    /**
     * 密碼編碼器
     */
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    /**
     * jwt增强器
     */
    @Autowired
    @Qualifier("jwtTokenEnhancer")
    private TokenEnhancer jwtTokenEnhancer;

    /**
     * jwttoken转换器
     */
    @Autowired
    @Qualifier("jwtAccessTokenConverter")
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    /**
     * 允许表单认证 不加会401
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security){
        security.allowFormAuthenticationForClients();
    }

    /**
     * 配置密码模式
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //整合jwt
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
        tokenEnhancers.add(jwtTokenEnhancer);
        tokenEnhancers.add(jwtAccessTokenConverter);
        tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);

        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService)
                //整合jwt
                .accessTokenConverter(jwtAccessTokenConverter)
                .tokenEnhancer(tokenEnhancerChain);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //从内存中获取，可以抽取变成从数据库中获取，进行多客户端接入
        clients.inMemory()
                //配置client_id
                .withClient(clientId)
                //配置client-secret
                .secret(passwordEncoder.encode(secret))
                //配置token的有效期
                .accessTokenValiditySeconds(tokenSecond)
                //配置刷新token的有效期
                .refreshTokenValiditySeconds(refreshTokenSecond)
                //配置申请的权限范围
                .scopes("all")
                /**
                 * authorization_code -根据授权码生成令牌
                 * client_credentials -客户端认证
                 * refresh_token -刷新令牌有效期
                 * password      -密码方式登录
                 */
                //配置grant_type,表示授权类型
                .authorizedGrantTypes("password","refresh_token");
    }
}
